const { ccclass, property } = cc._decorator;
import Skill from '../SkillBuild/Skill';
import MyEnums from '../MyEnums';
import SkillBtControl from "../SkillBuild/SkillBtControl";
import PickupControl from "./PickupControl";
import GLRandom from '../GLRandom ';
import SkillsNodeControl from '../SkillBuild/SkillsNodeControl'
import MonsterControl from '../Monster/MonsterControl';

class skillGL {
    Skillid: string;
    Prob: number;
    AwayTime: number;
}

@ccclass
export default class RandomPropControl extends cc.Component {
    @property(cc.Node)
    ObjectNode: cc.Node = null;
    @property(cc.Node)
    SkillButtons: cc.Node = null;
    @property(cc.Node)
    soundNode: cc.Node = null;
    @property(cc.Node)
    PickupNode: cc.Node = null;
    @property(cc.Node)
    skillNode: cc.Node = null;
    @property(cc.String)
    heropriteRoot: string = "Skills/";
    @property(cc.Prefab)
    _itemBtPrefab: cc.Prefab = null;
    @property(cc.Prefab)
    _pickupPrefab: cc.Prefab = null;
    @property(cc.SpriteAtlas)
    _icons: cc.SpriteAtlas = null;//技能图标
    @property(cc.SpriteAtlas)
    _elevate: cc.SpriteAtlas = null;//默认吃水果效果
    @property(cc.SpriteAtlas)
    _skillBtBg: cc.SpriteAtlas = null;//技能图标背景
    @property
    _SkillList: Map<string, cc.Node> = null;
    @property
    _SkillBt: Map<string, cc.Node> = null;
    @property
    _RandomJson: any = null;
    @property
    _mapIcon: Map<string, string> = null;
    @property
    _hitSkills: skillGL[] = [];
    @property
    _selfSkills: skillGL[] = [];
    @property
    _random: GLRandom = null;
    @property
    _SkillBtControl: SkillsNodeControl = null;
    @property
    _ParticlePrefab: Map<string, cc.Prefab> = null;

    init() {
        this._mapIcon = new Map();
        this._SkillList = new Map();
        this._SkillBt = new Map();
        this._hitSkills.forEach(element => {
            this.setSkill(MyEnums.SkillSource.public, MyEnums.attackType.hit, this.getParam(this._RandomJson.Hit, element.Skillid));
        });
        this._selfSkills.forEach(element => {
            this.setSkill(MyEnums.SkillSource.public, MyEnums.attackType.self, this.getParam(this._RandomJson.Self, element.Skillid));
        });
    }
    GetSkill(id: string): cc.Node {
        let _skillNode = this._SkillList.get(id);
        let node = cc.instantiate(_skillNode);
        return node;
    }
    GetSkillBt(id: string): cc.Node {
        return this._SkillBt.get(id);
    }
    getParam(param: any, id: string): skillGL {
        for (let index = 0; index < param.length; index++) {
            if (param[index].Id == id)
                return param[index];
        }
    }
    setSkillBt(id: string, title: string, effectType: number, icon: string): cc.Node {
        let node = cc.instantiate(this._itemBtPrefab);
        let skillBt = node.getComponent(SkillBtControl);
        node.name = id;
        skillBt._EffectType = effectType;
        skillBt.skillName = title;
        skillBt.skillId = id;
        skillBt.isRandomProp = true;
        skillBt.bgNode.getComponent(cc.Sprite).spriteFrame = this._skillBtBg.getSpriteFrame(MyEnums.SkillAttribute[effectType]);
        skillBt.loadNode.getComponent(cc.Sprite).spriteFrame = this._icons.getSpriteFrame(icon);
        return node;
    }
    /**
     * 获取技能
     * @param Source 攻击发出类型
     * @param attackType 施法类型
     * @param param 技能参数
     */
    setSkill(Source: number, attackType: number, param: any) {
        let NewNode = new cc.Node();
        NewNode.group = this.node.group;
        NewNode.name = param.Id;
        let _Skill = NewNode.addComponent(Skill);
        _Skill.soundNode = this.soundNode;
        _Skill.Source = Source;
        let spriteRoot: string = "";
        spriteRoot = this.heropriteRoot;
        _Skill.skillNode = this.skillNode;
        spriteRoot += param.Sprite;
        _Skill.icon = this._icons.getSpriteFrame(param.Icon);
        _Skill.id = param.Id;
        _Skill.title = param.Title;
        _Skill.explain = param.Explain;
        _Skill.attribute = param.Attribute;
        _Skill.Effect = param.IsEffect;
        if (param.IsEffect?.Particle)
            _Skill.EffectParticle = this._ParticlePrefab.get(param.IsEffect.Particle);
        _Skill.isSchedule = param.IsSchedule;
        _Skill.parentPosition = new cc.Vec2(0, param.SkillY);

        _Skill.attacks = param.Attacks;
        _Skill.attributes = param.Attributes;
        _Skill.attackType = attackType;
        _Skill.putType = param.PutType;
        this._mapIcon.set(param.Id, param.Icon);
        this.BuildSkill(NewNode, _Skill, spriteRoot, param.IsPlist);
        this._SkillBt.set(param.Id, this.setSkillBt(param.Id, param.Title, attackType, param.Icon));

        if (!param.IsStatus && attackType == MyEnums.attackType.self) {
            _Skill.Status = this.setDefultStatus();
            _Skill.sprites = this._elevate.getSpriteFrames();
            this._SkillList.set(_Skill.id, NewNode);
        }
        else {
            _Skill.Status = param.IsStatus;
            if (param.IsStatus.Particle) {
                _Skill.StatusParticle = this._ParticlePrefab.get(param.IsStatus.Particle);
            }
        }
    }
    BuildSkill(newNode: cc.Node, _Skill: Skill, path: string, isPlist: boolean) {
        let self = this;
        if (isPlist) {
            cc.resources.load(path, cc.SpriteAtlas, function (err, atlas) {
                if (!atlas || err) {
                    cc.log(err);
                    return;
                }
                _Skill.sprites = (atlas as cc.SpriteAtlas).getSpriteFrames()
                self._SkillList.set(_Skill.id, newNode);
            });
        }
        else {
            cc.resources.load(path, cc.SpriteFrame, function (err, atlas) {
                if (!atlas || err) {
                    cc.log(err);
                    return;
                }
                _Skill.sprite = (atlas as cc.SpriteFrame);
                self._SkillList.set(_Skill.id, newNode);
            });
        }
    }
    setDefultStatus(): any {
        let Status = {};
        Status["AnchorY"] = 0.5;
        Status["EveryLong"] = 0.5;
        Status["ScaleBy"] = 0;
        Status["Opacity"] = 255;
        Status["OpacityBy"] = 0;
        Status["Angle"] = 0;
        Status["Area"] = 0;
        Status["Sample"] = 3.0;
        Status["DoubleAngle"] = false;
        Status["Particle"] = "";
        Status["Sound"] = "bite";
        return Status;
    }
    getPickup(p: cc.Vec2) {
        let skillP = this.get_RandomSkill();
        if (skillP) {
            let node = cc.instantiate(this._pickupPrefab);
            let control = node.getComponent(PickupControl);
            control._skillBtNode = this.SkillButtons;
            control._RandomProp = this;
            control._skillSprite = this._icons.getSpriteFrame(this._mapIcon.get(skillP.Skillid));
            control._skillId = skillP.Skillid;
            control.awayTime = skillP.AwayTime;
            let p1 = this.ObjectNode.convertToNodeSpaceAR(p);
            node.setPosition(p1);
            this.ObjectNode.addChild(node);
        }
    }
    //概率获取技能ID
    get_RandomSkill(): skillGL {
        let max = this._hitSkills.length + this._selfSkills.length;
        if (!this._random) {
            this._random = new GLRandom(max);

            let mapGL: Map<number, number> = new Map();
            let i = 0;
            this._hitSkills.forEach(element => {
                mapGL.set(i, element.Prob);
                i++;
            });
            this._selfSkills.forEach(element => {
                mapGL.set(i, element.Prob);
                i++;
            });
            this._random.percentage = mapGL;
        }

        let xx = this._random.create();
        if (xx < this._hitSkills.length) {
            return this._hitSkills[xx];

        }
        else if (xx < max) {
            return this._selfSkills[xx - this._hitSkills.length];
        }
        return null;
    }
    addHeroBt(pickupNode: cc.Node, _skillId: string) {
        if (!this._SkillBtControl)
            this._SkillBtControl = this.SkillButtons.getComponent(SkillsNodeControl);
        this._SkillBtControl.addSkillRandomCount(_skillId, 1);
        pickupNode.destroy();
    }
    addMonsterBt(pickupNode: cc.Node, monster: cc.Node, _skillId: string) {
        pickupNode.destroy();
        let skill = this.GetSkill(_skillId);
        let mc = monster.getComponent(MonsterControl);
        let skillControl = skill.getComponent(Skill);
        skillControl.SourceNode = monster.getChildByName("launch");
        skillControl.Source = MyEnums.SkillSource.monster;
        skillControl.damageAttack = mc.attackDamage;
        skillControl.init();
        monster.getChildByName("Skills").addChild(skill);
    }
}
